package driver

import "gitee.com/gousing/cache/storage"

// ---------------------------------------
// L2Cache 简单集合实现
// SString String 字符串集合
// SInt    Int64 数值集合
// ---------------------------------------

// SStringAdd 向指定 key 的 String 集合添加一个或多个成员元素
//   - 如果指定 key 的集合不存在, 则新建集合并添加值到集合
//   - 如果指定 key 不是一个 String 集合, 则返回错误
//   - 如果指定 key 的集合存在, 则添加值到集合
//   - 如果 items为空, 则什么也不做, 直接返回nil
func (c *L2Cache) SStringAdd(key string, items ...string) error {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	if len(items) == 0 {
		return nil
	}
	c.remote.SStringAdd(key, items...)
	return c.local.SStringAdd(key, items...)
}

// SStringRemove 从指定 key 的 String 集合中移除一个或多个成员
//   - 如果指定 key 的集合不存或不是一个 String 集合, 则返回错误
//   - 如果items为空, 则什么也不做, 直接返回nil
func (c *L2Cache) SStringRemove(key string, items ...string) error {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	if len(items) == 0 {
		return nil
	}
	c.remote.SStringRemove(key, items...)
	return c.local.SStringRemove(key, items...)
}

// SStringClear 清空指定 key 的 String 集合
//   - 如果指定 key 的集合不存或不是一个 String 集合, 则返回错误
func (c *L2Cache) SStringClear(key string) error {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	c.remote.SStringClear(key)
	return c.local.SStringClear(key)
}

// SStringContains 判断一个或多个成员是否全部在指定 key 的 String 集合中
//   - 如果指定 key 的集合不存或不是一个 String 集合, 则返回 false
//   - 查询多个成员, 任意一个成员不在集合中, 则返回 false
func (c *L2Cache) SStringContains(key string, items ...string) bool {
	if key == "" {
		return false
	}
	if len(items) == 0 {
		return false
	}
	if c.local.SStringContains(key, items...) {
		return true
	}
	if c.remote.SStringContains(key, items...) {
		c.loadFromRedis(key)
		return true
	}
	return false
}

// SStringContainsSome 判断一个或多个成员的中任意一个成员是否在指定 key 的 String 集合中
//   - 如果指定 key 的集合不存或不是一个 String 集合, 则返回 false
//   - 查询多个成员, 任意一个成员存在集合中, 则返回 true
func (c *L2Cache) SStringContainsSome(key string, items ...string) bool {
	if key == "" {
		return false
	}
	if len(items) == 0 {
		return false
	}
	if c.local.SStringContainsSome(key, items...) {
		return true
	}
	if c.remote.SStringContainsSome(key, items...) {
		c.loadFromRedis(key)
		return true
	}
	return false
}

// SStringMembers 获取指定 key 的 String 集合的所有成员
//   - 如果指定 key 的集合不存或不是一个 String 集合, 则返回错误
func (c *L2Cache) SStringMembers(key string) ([]string, error) {
	if key == "" {
		return nil, storage.ErrKeyIsEmpty
	}

	if val, err := c.local.SStringMembers(key); err == nil {
		return val, nil
	}
	if val, err := c.remote.SStringMembers(key); err == nil {
		c.loadFromRedis(key)
		return val, nil
	}
	return nil, storage.ErrKeyNotExists
}

// SStringTraverse 遍历指定 key 的 String 集合的所有成员
//   - 如果指定 key 的集合不存或不是一个 String 集合, 则返回错误
//   - fn 签名是 iter.Seq[string], 迭代过程中, 返回 false 则停止遍历
func (c *L2Cache) SStringTraverse(key string, fn func(string) bool) error {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	err := c.local.SStringTraverse(key, fn)
	if err != nil {
		err = c.remote.SStringTraverse(key, fn)
		if err == nil {
			c.loadFromRedis(key)
		}
	}
	return err
}

// SStringSize 获取指定 key 的 String 集合的成员数量
//   - 如果指定 key 的集合不存或不是一个 String 集合, 则返回错误
func (c *L2Cache) SStringSize(key string) (int64, error) {
	if key == "" {
		return 0, storage.ErrKeyIsEmpty
	}
	if val, err := c.local.SStringSize(key); err == nil {
		return val, nil
	}
	if val, err := c.remote.SStringSize(key); err == nil {
		c.loadFromRedis(key)
		return val, nil
	}
	return 0, storage.ErrKeyNotExists
}

// SIntAdd 向指定 key 的 Int64 集合添加一个或多个成员元素
//   - 如果指定 key 的集合不存在, 则新建集合并添加值到集合
//   - 如果指定 key 不是一个 Int64 集合, 则返回错误
//   - 如果指定 key 的集合存在, 则添加值到集合
//   - 如果 items为空, 则什么也不做, 直接返回nil
func (c *L2Cache) SIntAdd(key string, items ...int64) error {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	if len(items) == 0 {
		return nil
	}
	c.remote.SIntAdd(key, items...)
	return c.local.SIntAdd(key, items...)
}

// SIntRemove 从指定 key 的 Int64 集合中移除一个或多个成员
//   - 如果指定 key 的集合不存或不是一个 Int64 集合, 则返回错误
//   - 如果items为空, 则什么也不做, 直接返回nil
func (c *L2Cache) SIntRemove(key string, items ...int64) error {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	if len(items) == 0 {
		return nil
	}
	c.remote.SIntRemove(key, items...)
	return c.local.SIntRemove(key, items...)
}

// SIntClear 清空指定 key 的 Int64 集合
//   - 如果指定 key 的集合不存或不是一个 Int64 集合, 则返回错误
func (c *L2Cache) SIntClear(key string) error {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	c.remote.SIntClear(key)
	return c.local.SIntClear(key)
}

// SIntContains 判断一个或多个成员是否全部在指定 key 的 Int64 集合中
//   - 如果指定 key 的集合不存或不是一个 Int64 集合, 则返回 false
//   - 查询多个成员, 任意一个成员不在集合中, 则返回 false
func (c *L2Cache) SIntContains(key string, items ...int64) bool {
	if key == "" {
		return false
	}
	if len(items) == 0 {
		return false
	}
	if c.local.SIntContains(key, items...) {
		return true
	}
	if c.remote.SIntContains(key, items...) {
		c.loadFromRedis(key)
		return true
	}
	return false
}

// SIntContainsSome 判断一个或多个成员的中任意一个成员是否在指定 key 的 Int64 集合中
//   - 如果指定 key 的集合不存或不是一个 Int64 集合, 则返回 false
//   - 查询多个成员, 任意一个成员存在集合中, 则返回 true
func (c *L2Cache) SIntContainsSome(key string, items ...int64) bool {
	if key == "" {
		return false
	}
	if len(items) == 0 {
		return false
	}
	if c.local.SIntContainsSome(key, items...) {
		return true
	}
	if c.remote.SIntContainsSome(key, items...) {
		c.loadFromRedis(key)
		return true
	}
	return false
}

// SIntMembers 获取指定 key 的 Int64 集合的所有成员
//   - 如果指定 key 的集合不存或不是一个 Int64 集合, 则返回错误
func (c *L2Cache) SIntMembers(key string) ([]int64, error) {
	if key == "" {
		return nil, storage.ErrKeyIsEmpty
	}

	if val, err := c.local.SIntMembers(key); err == nil {
		return val, nil
	}
	if val, err := c.remote.SIntMembers(key); err == nil {
		c.loadFromRedis(key)
		return val, nil
	}
	return nil, storage.ErrKeyNotExists
}

// SIntTraverse 遍历指定 key 的 Int64 集合的所有成员
//   - 如果指定 key 的集合不存或不是一个 Int64 集合, 则返回错误
//   - fn 签名是 iter.Seq[int64], 迭代过程中, 返回 false 则停止遍历
func (c *L2Cache) SIntTraverse(key string, fn func(int64) bool) error {
	if key == "" {
		return storage.ErrKeyIsEmpty
	}
	err := c.local.SIntTraverse(key, fn)
	if err != nil {
		err = c.remote.SIntTraverse(key, fn)
		if err == nil {
			c.loadFromRedis(key)
		}
	}
	return err
}

// SIntSize 获取指定 key 的 Int64 集合的成员数量
//   - 如果指定 key 的集合不存或不是一个 Int64 集合, 则返回错误
func (c *L2Cache) SIntSize(key string) (int64, error) {
	if key == "" {
		return 0, storage.ErrKeyIsEmpty
	}
	if val, err := c.local.SIntSize(key); err == nil {
		return val, nil
	}
	if val, err := c.remote.SIntSize(key); err == nil {
		c.loadFromRedis(key)
		return val, nil
	}
	return 0, storage.ErrKeyNotExists
}
